package com.jlcloud.core.xss;

import com.jlcloud.core.xss.annotation.XssIgnore;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import com.jlcloud.core.tool.utils.ClassUtil;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

import java.util.List;

/**
 * xss 处理拦截器
 *
 * @author By: JlCloud <br>
 * @Package: com.jlcloud <br>
 * @CreateTime: 2024-12-03 21:45 <br>
 * @Copyright: 2021 www.jilianjituan.com Inc. All rights reserved. <br>
 * @Caution 注意：本内容仅限于冀联人力集团内部传阅，禁止外泄以及用于其他的商业目的 <br>
 */
@RequiredArgsConstructor
public class XssInterceptor implements AsyncHandlerInterceptor {
	private final PathMatcher matcher = new AntPathMatcher();
	private final JlCloudXssProperties xssProperties;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		// 1. 非控制器请求直接跳出
		if (!(handler instanceof HandlerMethod)) {
			return true;
		}
		// 2. 没有开启
		if (!xssProperties.isEnabled()) {
			return true;
		}
		// 判断是否需要跳过
		List<String> skipUrl = xssProperties.getSkipUrl();
		String requestURL = request.getRequestURI();
		boolean needExclude = skipUrl.stream()
			.anyMatch(pattern -> matcher.match(pattern, requestURL));
		if (needExclude) {
			XssHolder.setIgnore(new XssIgnoreRules());
			return true;
		}
		// 3. 处理 XssIgnore 注解
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		XssIgnore xssIgnore = ClassUtil.getAnnotation(handlerMethod, XssIgnore.class);
		if (xssIgnore != null) {
			XssHolder.setIgnore(new XssIgnoreRules(xssIgnore.value()));
		}
		return true;
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		XssHolder.remove();
	}

	@Override
	public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		XssHolder.remove();
	}
}
